package me.ingxin.android.rv

import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView

/**
 * Created by ingxin on 2022/7/5
 * 为网格布局添加分割间距
 * @param spaceH 网格之间水平方向间距
 * @param spaceV 网格之间竖直方向间距
 */
open class GridItemDecoration @JvmOverloads constructor(
    private val spaceH: Int,
    private val spaceV: Int = spaceH
) : RecyclerView.ItemDecoration() {

    private val cache = HashMap<Int, Pair<Int, Int>>()

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        val position = parent.getChildAdapterPosition(view)
        if (position == RecyclerView.NO_POSITION) {
            return
        }
        val layoutManager = (parent.layoutManager as? GridLayoutManager) ?: return
        val itemCount = layoutManager.itemCount
        if (itemCount == 0) {
            return
        }

        //网格列数
        val spanCount = layoutManager.spanCount
        //总的行数
        val rowCount = (itemCount + spanCount - 1) / spanCount
        //当前行index
        val rowIndex = position / spanCount

        if (rowIndex == rowCount - 1) {
            //最后一行
            outRect.bottom = 0
        } else {
            outRect.bottom = spaceV
        }

        val k = (spanCount * spaceH - spaceH) / spanCount
        val pair = getHorizontalMargin(position % spanCount, spaceH, k)
        outRect.left = pair.first
        outRect.right = pair.second
    }

    /**
     * 获取指定列的左右间距
     * @param columnIndex 列的索引
     * @param itemSpace item之间的间距
     * @param k 平局分配到每个item的左右间距之和
     * @return  Pair.first表示左间距，Pair.second表示右间距
     */
    private fun getHorizontalMargin(columnIndex: Int, itemSpace: Int, k: Int): Pair<Int, Int> {
        if (columnIndex == 0) {
            return 0 to k
        }

        var prev = cache[columnIndex - 1]
        if (prev == null) {
            prev = getHorizontalMargin(columnIndex - 1, itemSpace, k)
            cache[columnIndex - 1] = prev
        }
        val left = itemSpace - prev.second
        val right = k - left
        return left to right
    }

}